home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- subject: v08i027: Microport System V/286 pty driver
- Reply-To: jay@splut.conmicro.com (Jay "you ignorant splut!" Maynard)
-
- Posting-number: Volume 8, Issue 27
- Submitted-by: jay@splut.conmicro.com (Jay "you ignorant splut!" Maynard)
- Archive-name: pty_uport
-
- I've had sporadic requests for this one.
- It's a gross, unsubtle hack based on Jens-Uwe Mager's original, with
- Michael Bloom's mode incorporated as well (he did the hard work).
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: READ_ME READ_ME.orig pty.c mkpty
- # Wrapped by jay@splut on Sat Sep 2 17:44:40 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f READ_ME -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"READ_ME\"
- else
- echo shar: Extracting \"READ_ME\" \(1487 characters\)
- sed "s/^X//" >READ_ME <<'END_OF_READ_ME'
- XThis version of the pty driver has been hacked upon until it worked under
- XMicroport System V/AT. It's probably full of system no-nos, as I am no
- Xkernel hacker. In particular, the declaration of pty_tty[] and pty_stat[] is
- Xhorribly wrong; if you know the right way to do that, PLEASE let me
- Xknow. I have tested it under System V/AT versions 2.3 and 2.4, and it
- Xappears to work. This version does NOT work as-is under System V/386.
- X
- XThe required lines for the master file are:
- X
- Xpts 0 ocrwi ct pts 0 14 32
- Xptm 0 ocrwi c ptm 0 15 32
- X ^^---major device number;
- X change these if you have
- X conflicts with other
- X device drivers
- X
- Xand for the dfile:
- X
- Xpts 0 32
- Xptm 0 32
- X
- XThis can be installed using the usual driver installation:
- X1) Put pty.c in /usr/linkkit/io.
- X2) cd to /usr/linkkit/io, then:
- X cc -c -Ml -O pty.c
- X ar r ../lib2 pty.o
- X ^--------if your lib2 fills up, create a new one (I
- X used lib5; it must be lib[0-9])
- X3) Become superuser, and then:
- X cd /usr/linkkit/cf
- X [edit master, dfile.wini if you haven't]
- X make wini
- X4) The file /usr/linkkit/system5 can be installed as your kernel and
- Xbooted.
- X5) The mkpty shell script will automagically build 32 master and slave
- Xdevice files. It will figure out which major device numbers you assigned.
- X
- XGood luck...Jay
- X
- END_OF_READ_ME
- if test 1487 -ne `wc -c <READ_ME`; then
- echo shar: \"READ_ME\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f READ_ME.orig -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"READ_ME.orig\"
- else
- echo shar: Extracting \"READ_ME.orig\" \(1624 characters\)
- sed "s/^X//" >READ_ME.orig <<'END_OF_READ_ME.orig'
- XThis is a pseudo tty driver for system V machines. It works very
- Xsimilar to ptys on BSD, for instance emacs works fine. To install this
- Xdriver you will need to modify your `master' and `dfile' file which
- Xcontains your driver specifications. As these vary from machine to machine,
- Xyou will have to look up in your manual how to do that. Here is an example
- Xfor a sperry s5050 alias ncr tower 32 :
- X
- XAdd the following two lines to the driver description section in master:
- Xpts 0 237 244 pts 0 0 28 32 0 tty
- Xptm 0 37 344 ptm 0 0 29 0 0
- X
- XThis says there are max 32 pts devices at major number 28 having associated
- Xtty structures and 0 ptm devices having major number 29 with no associated
- Xdata. The number of ptm devices is not configurable, as this depends on the
- Xnumber of pts's.
- X
- XThe following two lines go in the dfile:
- Xpts 0 0 0
- Xptm 0 0 0
- X
- XProbably you will also want to increase the NCLIST parameter.
- X
- XIf your configuration procedure is different, you must change the shell
- Xscript mkpty, which is used to create the device nodes in /dev.
- X
- XThe ptm devices (/dev/pty[p-z][0-9a-f]) are the controlling ones, everything
- Xwritten there will show up at the associated pts device
- X(/dev/tty[p-z][0-9a-f]), as well as erverything which is written on the pts
- Xdevice will show up on the ptm device. The pts side will accept the usual
- Xtermio ioctl calls. The master side is a bit different, as ioctl calls which
- Xnormally wait for output to drain flush output. The reason for this funny
- Xbehaviour is that otherwise the master side will hang. Also the master side
- Xmay be opened only once, further open calls will result in an EBUSY error.
- END_OF_READ_ME.orig
- if test 1624 -ne `wc -c <READ_ME.orig`; then
- echo shar: \"READ_ME.orig\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f pty.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"pty.c\"
- else
- echo shar: Extracting \"pty.c\" \(8704 characters\)
- sed "s/^X//" >pty.c <<'END_OF_pty.c'
- X/*
- X * pty.c - Berkeley style pseudo tty driver for system V
- X *
- X * Additions marked:
- X * TTI - for the changes made by Michael Bloom at Citicorp/TTI to make
- X * it not Sperry 5000-series dependent. He did all the hard work.
- X * The original code used some unused bits in the tty structure;
- X * they turned out to be only unused in the Sperry/NCR Tower version.
- X * He added the code to move the status bits out. He also added the
- X * DEBUG code, which helped me to understand a little better how
- X * the bytes flowed.
- X * JRM - my unsubtle hacks to make it work with Microport.
- X *
- X * Other portions:
- X * Copyright (c) 1987, Jens-Uwe Mager, FOCUS Computer GmbH
- X * Not derived from licensed software.
- X *
- X * Permission is granted to freely use, copy, modify, and redistribute
- X * this software, provided that no attempt is made to gain profit from it,
- X * the author is not construed to be liable for any results of using the
- X * software, alterations are clearly marked as such, and this notice is
- X * not modified.
- X */
- X#define MAXPTYS 32
- X
- X/* TTI: */
- X#define MRWAIT 01 /* master waiting in read */
- X#define t_rloc t_cc[0] /* rchannel */
- X
- X#define MWWAIT 02 /* master waiting in write */
- X#define t_wloc t_cc[1] /* wchannel */
- X
- X#define MOPEN 04 /* master is open */
- X/* end TTI */
- X
- X#include "sys/param.h"
- X#include "sys/types.h"
- X#include "sys/sysmacros.h"
- X#include "sys/seg.h"
- X#include "sys/systm.h"
- X#include "sys/file.h"
- X#include "sys/conf.h"
- X
- X/* JRM: following removed
- X#include "sys/page.h"
- X#include "sys/immu.h"
- X#include "sys/region.h"
- X*/
- X
- X#include "sys/proc.h"
- X#include "sys/dir.h"
- X#include "sys/tty.h"
- X#include "sys/signal.h"
- X#include "sys/user.h"
- X#include "sys/errno.h"
- X#include "sys/termio.h"
- X#include "sys/ttold.h"
- X
- X/* JRM:
- X * note: this is not subtle...if you know of a slick way to get this from
- X * config, please tell me about it! */
- Xextern int pts_cnt;
- Xstruct tty pts_tty[MAXPTYS];
- Xint pts_state[MAXPTYS];
- X
- X/*
- X * slave side is a fairly standard system V tty driver
- X */
- Xptsopen(fdev, flag) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X extern int ptsproc();
- X
- X if (dev >= pts_cnt) {
- X u.u_error = ENXIO;
- X return;
- X }
- X if ((tp->t_state & (ISOPEN|WOPEN)) == 0) {
- X ttinit(tp);
- X tp->t_proc = ptsproc;
- X }
- X /*
- X * if master is still open, don't wait for carrier
- X */
- X if (pts_state[dev] & MOPEN) /* TTI */
- X tp->t_state |= CARR_ON;
- X if (!(flag & FNDELAY)) {
- X while ((tp->t_state & CARR_ON) == 0) {
- X tp->t_state |= WOPEN;
- X sleep((caddr_t)&tp->t_canq, TTIPRI);
- X }
- X }
- X (*linesw[tp->t_line].l_open)(tp);
- X}
- X
- Xptswrite(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X#ifdef DEBUG
- X printf("T_TIME\n"); /* TTI */
- X#endif DEBUG
- X (*linesw[tp->t_line].l_write)(tp);
- X}
- X
- Xptsread(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X (*linesw[tp->t_line].l_read)(tp);
- X}
- X
- Xptsclose(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X (*linesw[tp->t_line].l_close)(tp);
- X tp->t_state &= ~CARR_ON;
- X}
- X
- Xptsioctl(fdev, cmd, arg, mode)
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X ttiocom(tp, cmd, arg, mode);
- X}
- X
- Xptsproc(tp, cmd)
- Xregister struct tty *tp;
- X{
- X register struct ccblock *tbuf;
- X extern ttrstrt();
- X
- X switch (cmd) {
- X case T_TIME:
- X#ifdef DEBUG
- X printf("T_TIME\n"); /* TTI */
- X#endif
- X tp->t_state &= ~TIMEOUT;
- X goto start;
- X case T_WFLUSH:
- X#ifdef DEBUG
- X printf("T_WFLUSH\n"); /* TTI */
- X#endif
- X tp->t_tbuf.c_size -= tp->t_tbuf.c_count;
- X tp->t_tbuf.c_count = 0;
- X /* fall through */
- X case T_RESUME:
- X#ifdef DEBUG
- X printf("T_RESUME\n"); /* TTI */
- X#endif
- X tp->t_state &= ~TTSTOP;
- X /* fall through */
- X case T_OUTPUT:
- X#ifdef DEBUG
- X printf("T_OUTPUT\n"); /* TTI */
- X#endif
- Xstart:
- X if (tp->t_state & (TTSTOP|TIMEOUT))
- X break;
- X tbuf = &tp->t_tbuf;
- X if (tbuf->c_ptr == NULL || tbuf->c_count == 0) {
- X if (tbuf->c_ptr)
- X tbuf->c_ptr -= tbuf->c_size;
- X if (!(CPRES & (*linesw[tp->t_line].l_output)(tp)))
- X break;
- X }
- X if (tbuf->c_count && (pts_state[tp-pts_tty] & MRWAIT)) {
- X pts_state[tp-pts_tty] &= ~MRWAIT; /* TTI */
- X wakeup((caddr_t)&tp->t_rloc);
- X }
- X break;
- X case T_SUSPEND:
- X#ifdef DEBUG
- X printf("T_SUSPEND\n"); /* TTI */
- X#endif
- X tp->t_state |= TTSTOP;
- X break;
- X case T_BLOCK:
- X#ifdef DEBUG
- X printf("T_BLOCK\n"); /* TTI */
- X#endif
- X /*
- X * the check for ICANON appears to be neccessary
- X * to avoid a hang when overflowing input
- X */
- X if ((tp->t_iflag & ICANON) == 0)
- X tp->t_state |= TBLOCK;
- X break;
- X case T_BREAK:
- X#ifdef DEBUG
- X printf("T_BREAK\n"); /* TTI */
- X#endif
- X tp->t_state |= TIMEOUT;
- X timeout(ttrstrt, tp, HZ/4);
- X break;
- X#ifdef T_LOG_FLUSH
- X case T_LOG_FLUSH:
- X#ifdef DEBUG
- X printf("T_LOG_FLUSH\n"); /* TTI */
- X#endif
- X#endif
- X case T_RFLUSH:
- X#ifdef DEBUG
- X printf("T_RFLUSH\n"); /* TTI */
- X#endif
- X if (!(tp->t_state & TBLOCK))
- X break;
- X /* fall through */
- X case T_UNBLOCK:
- X#ifdef DEBUG
- X printf("T_UNBLOCK\n"); /* TTI */
- X#endif
- X tp->t_state &= ~(TTXOFF|TBLOCK);
- X /* fall through */
- X case T_INPUT:
- X#ifdef DEBUG
- X printf("T_INPUT\n"); /* TTI */
- X#endif
- X if (pts_state[tp-pts_tty] & MWWAIT) {
- X pts_state[tp-pts_tty] &= ~MWWAIT; /* TTI */
- X wakeup((caddr_t)&tp->t_wloc);
- X }
- X break;
- X#ifdef DEBUG
- X default: /* TTI */
- X printf("ptsproc: cmd %d\n",cmd);
- X#endif
- X }
- X}
- X
- X/*
- X * master part - not actually like a tty
- X */
- X
- Xptmopen(fdev, flag) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X#ifdef DEBUG
- X printf("ptmopen(%d)\n",dev); /* TTI */
- X#endif
- X if (dev >= pts_cnt) {
- X u.u_error = ENXIO;
- X return;
- X }
- X /*
- X * allow only one controlling process
- X */
- X if (pts_state[dev] & MOPEN) { /* TTI */
- X u.u_error = EBUSY;
- X return;
- X }
- X if (tp->t_state & WOPEN)
- X wakeup((caddr_t)&tp->t_canq);
- X tp->t_state |= CARR_ON; /* TTI */
- X pts_state[dev] |= MOPEN;
- X}
- X
- Xptmread(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X register n;
- X
- X if ((tp->t_state & (ISOPEN|TTIOW)) == 0) { /* TTI */
- X#ifdef DEBUG
- X printf("ptmread(%d) EIO\n",dev); /* TTI */
- X#endif
- X u.u_error = EIO;
- X return;
- X }
- X#ifdef DEBUG
- X printf("ptmread(%d)\n",dev); /* TTI */
- X#endif
- X while (u.u_count>0) { /* TTI */
- X ptsproc(tp, T_OUTPUT);
- X if ((tp->t_state & (TTSTOP|TIMEOUT))
- X || tp->t_tbuf.c_ptr == NULL || tp->t_tbuf.c_count == 0) {
- X if (u.u_fmode & FNDELAY)
- X break;
- X pts_state[dev] |= MRWAIT; /* TTI */
- X sleep((caddr_t)&tp->t_rloc, TTIPRI);
- X continue;
- X }
- X n = min(u.u_count, tp->t_tbuf.c_count);
- X if (n) {
- X if (copyout(tp->t_tbuf.c_ptr, u.u_base, n)) {
- X u.u_error = EFAULT;
- X break;
- X }
- X tp->t_tbuf.c_count -= n;
- X tp->t_tbuf.c_ptr += n;
- X u.u_base += n;
- X u.u_count -= n;
- X break; /* JRM: added - without this, the flow from
- X slave to master is buffered */
- X }
- X }
- X}
- X
- Xptmwrite(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X register n;
- X
- X if ((tp->t_state & ISOPEN) == 0) {
- X u.u_error = EIO;
- X return;
- X }
- X#ifdef DEBUG
- X printf("ptmwrite(%d)\n",dev); /* TTI */
- X#endif
- X while (u.u_count>0) { /* TTI */
- X if ((tp->t_state & TBLOCK) || tp->t_rbuf.c_ptr == NULL) {
- X if (u.u_fmode & FNDELAY)
- X break;
- X pts_state[dev] |= MWWAIT; /* TTI */
- X sleep((caddr_t)&tp->t_wloc, TTOPRI);
- X continue;
- X }
- X n = min(u.u_count, tp->t_rbuf.c_count);
- X if (n) {
- X if (copyin(u.u_base,tp->t_rbuf.c_ptr, n)) {
- X u.u_error = EFAULT;
- X break;
- X }
- X tp->t_rbuf.c_count -= n;
- X u.u_base += n;
- X u.u_count -= n;
- X }
- X#ifdef vax || m68k /* TTI */
- X /*
- X * somebody told me this is necessary on the vax
- X */
- X (*linesw[tp->t_line].l_input)(tp, L_BUF);
- X#else
- X (*linesw[tp->t_line].l_input)(tp);
- X#endif
- X }
- X}
- X
- Xptmclose(fdev) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X#ifdef DEBUG
- X printf("ptmclose(%d)\n",dev); /* TTI */
- X#endif
- X if (tp->t_state & ISOPEN) {
- X signal(tp->t_pgrp, SIGHUP);
- X ttyflush(tp, FREAD|FWRITE);
- X }
- X /*
- X * virtual carrier gone
- X */
- X tp->t_state &= ~CARR_ON; /* TTI */
- X pts_state[dev] &= ~MOPEN;
- X}
- X
- Xptmioctl(fdev, cmd, arg, mode) /* TTI */
- X{
- X register dev = minor(fdev); /* TTI */
- X register struct tty *tp = &pts_tty[dev];
- X
- X /*
- X * sorry, but we can't fiddle with the tty struct without
- X * having done LDOPEN
- X */
- X if (tp->t_state & ISOPEN) {
- X if (cmd == TCSBRK && arg == NULL) {
- X signal(tp->t_pgrp, SIGINT);
- X if ((tp->t_iflag & NOFLSH) == 0)
- X ttyflush(tp, FREAD|FWRITE);
- X } else {
- X /*
- X * we must flush output to avoid hang in ttywait
- X */
- X if (cmd == TCSETAW || cmd == TCSETAF || cmd == TCSBRK
- X || cmd == TIOCSETP)
- X ttyflush(FWRITE);
- X ttiocom(tp, cmd, arg, mode);
- X }
- X }
- X}
- END_OF_pty.c
- if test 8704 -ne `wc -c <pty.c`; then
- echo shar: \"pty.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f mkpty -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"mkpty\"
- else
- echo shar: Extracting \"mkpty\" \(451 characters\)
- sed "s/^X//" >mkpty <<'END_OF_mkpty'
- X:
- X#!/bin/sh
- Xsmajor=`grep pts /usr/linkkit/cf/master|cut -f7`
- Xmmajor=`grep ptm /usr/linkkit/cf/master|cut -f7`
- Xndevs=`grep pts_cnt /usr/linkkit/cf/conf.c|sed 's/int pts_cnt = \([0-9]*\);/\1/'`
- Xminor=0
- Xfor x in p q r s t u v w x y z
- Xdo
- X for y in 0 1 2 3 4 5 6 7 8 9 a b c d e f
- X do
- X i=$x$y
- X if [ $minor -ge $ndevs ]; then break; fi
- X /etc/mknod /dev/pty$i c $mmajor $minor
- X /etc/mknod /dev/tty$i c $smajor $minor
- X minor=`expr $minor + 1`
- X done
- Xdone
- END_OF_mkpty
- if test 451 -ne `wc -c <mkpty`; then
- echo shar: \"mkpty\" unpacked with wrong size!
- fi
- chmod +x mkpty
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
- --
- Jay Maynard, EMT-P, K5ZC, PP-ASEL | Never ascribe to malice that which can
- jay@splut.conmicro.com (eieio)| adequately be explained by stupidity.
- {attctc,bellcore}!texbell!splut!jay +----------------------------------------
- "Rabid rerouters *love* to route mail to devnull@hell.org" - Brandon Allbery
-
-